using System;
using System.Collections.Generic;
using System.Text;
using virtuaPol.Util;

namespace virtuaPol.Model
{
    [Serializable]
    [System.Xml.Serialization.XmlRoot("scenario", Namespace="", IsNullable=false)]
    public class CWorld : INamedObject
    {
        // Initial size of the country list (use this to optimize class)
        public const string DUMMY_COUNTRY_NAME = "[DUMMY]";
        public const string DUMMY_PROPERTY_NAME = "[DUMMY]";

        // Locker object for thread safety
        private object _locker = new object();

        private string name;
        [System.Xml.Serialization.XmlAttribute("name")]
        public string Name {
            get { lock (_locker) { return name; } }
            set { lock (_locker) { name = value; } }
        }

        private string author;
        [System.Xml.Serialization.XmlAttribute("author")]
        public string Author {
            get { lock (_locker) { return author; } }
            set { lock (_locker) { author = value; } }
        }

        private int version;
        [System.Xml.Serialization.XmlAttribute("version")]
        public int Version {
            get { lock (_locker) { return version; } }
            set { lock (_locker) { version = value; } }
        }

        private string playerCountryKey;
        [System.Xml.Serialization.XmlAttribute("playerCountry")]
        public string PlayerCountryKey {
            get { lock (_locker) { return playerCountryKey; } }
            set { lock (_locker) { playerCountryKey = value; } }
        }

        private ExtendedList<CCountry> countries = new ExtendedList<CCountry>();
        [System.Xml.Serialization.XmlArray("countries")]
        public ExtendedList<CCountry> Countries
        {
            get { lock (_locker) { return countries; } }
            set { lock (_locker) { countries = value; } }
        }

        private ExtendedList<CEvent> events = new ExtendedList<CEvent>();
        [System.Xml.Serialization.XmlArray("events")]
        public ExtendedList<CEvent> Events
        {
            get { lock (_locker) { return events; } }
            set { lock (_locker) { events = value; } }
        }

        private ExtendedList<CProperty> properties =
            new ExtendedList<CProperty>();
        [System.Xml.Serialization.XmlArray("properties")]
        public ExtendedList<CProperty> Properties
        {
            get { lock (_locker) { return properties; } }
            set { lock (_locker) { properties = value; } }
        }

        public CWorld()
        { }

        public CWorld(string name)
        {
            Name = name;
            // Add dummy elements
            Countries.Add(new CCountry(DUMMY_COUNTRY_NAME));
            Properties.Add(new CProperty(DUMMY_PROPERTY_NAME, CPropertyValueTypes.Integer, 0));
        }

        public bool addCountry(CCountry c)
        {
            bool result = false;
            try
            {
                Countries.Add(c);
                result = true;
            }
            catch (Exception ex) { result = false; }
            return result;
        }

        public CCountry getCountryByName(string name)
        {
            if (Countries.Contains(name))
                return Countries[name];
            else
                return null;
        }

        public CCountry getCountryByIndex(int index)
        {
            return Countries[index];
        }

        public bool addEvent(CEvent ev)
        {
            bool result = false;
            try
            {
                Events.Add(ev);
                result = true;
            }
            catch (Exception ex) { result = false; }
            return result;
        }

        public CEvent getEventByName(string name)
        {
            if (Events.Contains(name))
                return Events[name];
            else
                return null;
        }

        public CEvent getEventByIndex(int index)
        {
            return Events[index];
        }

        public bool addProperty(CProperty p)
        {
            bool result = false;
            try
            {
                Properties.Add(p);
                result = true;
            }
            catch (Exception ex) { result = false; }
            return result;
        }

        public CProperty getPropertyByName(string name)
        {
            if (Properties.Contains(name))
                return Properties[name];
            else
                return null;
        }

        public CProperty getPropertyByIndex(int index)
        {
            return Properties[index];
        }

        public CCountry getPlayerCountry()
        {
            return getCountryByName(PlayerCountryKey);
        }

        public void movePerson(CPerson p, CCountry src, CCountry dest)
        {
            src.removePerson(p);
            dest.addPerson(p);
        }
    }
}
